import { ref, reactive, watch, toRefs } from "vue";
import Navication from "@/json/navigation.json";
import { useRouter, useRoute } from "vue-router";
import { INavigationItem } from "@/interface";
import { sideMinWidth, sideWidth } from '@/config/layout';
const primaryColor = "#409EFF";

const useNavigation = <T>(props: any, _this: any, args?: T & any) => {
  const { $bg } = toRefs(args);
  
  /* 定义一些变量 */
  const navication = reactive(Navication);
  const navicationDom = ref<HTMLElement | null>(null);
  const router = useRouter();
  const route = useRoute();
  const HEIGHT = 50;
  const trigger = ref(true);
  const defaultActive = Navication[0].name;
  const actived = ref(defaultActive);
  /* 监听 */
  watch(trigger, (v) => {
    if (v) {
      (navicationDom.value as HTMLElement).style.width = sideWidth;
      changeState("remove");
      activeIndex();
    } else {
      (navicationDom.value as HTMLElement).style.width = sideMinWidth;
      changeState("add");
      autoCloseMenu();
    }
    _this.emit("trigger", v);
  })

  /* 定义方法 */

  // 是否展开状态变化
  const changeState = (key: "remove" | "add") => {
    const parents = (navicationDom.value as HTMLElement).querySelectorAll(".item");
    parents.forEach((parent: Element) => {
      const children = parent.children;
      const len = children.length;
      if (len === 2) {
        children[1].classList[key]("v-none");
      } else if (len === 3) {
        children[1].classList[key]("v-none");
        children[2].classList[key]("v-none");
      }
    });
  }

  // 自动关闭展开的子菜单
  const autoCloseMenu = () => {
    const boxes = document.getElementsByClassName("box");
    [...boxes].forEach((elm: any) => {
      const isExpand = elm.dataset.show;
      if (isExpand == 1) {
        // 将打开的导航栏关闭
        shiftNavShowState(createEventObj(elm), true);
        // 将父节点的move设置为active状态
        const move = elm.querySelector(".move");
        move.classList.add("active-move");
      }
    });
  }

  const setAttrs = (elm: HTMLElement, attrs: any) => {
    if (attrs && Object.keys(attrs).length > 0) {
      for (let key in attrs) {
        elm.setAttribute(key, attrs[key]);
      }
    }
  };

  const setText = (elm: HTMLElement, text?: string) => {
    if (text) {
      elm.innerHTML = text;
    }
  };

  // 创建元素
  const createElement = (tagName: string, attrs: Object, text?: string) => {
    const elm = document.createElement(tagName);
    setAttrs(elm, attrs);
    setText(elm, text);
    return elm;
  };

  const createIcon = (icon: string, small?: boolean) => {
    const cls = small ? "icon icon-small" : "icon";
    return `
              <svg class="${cls}" aria-hidden="true">
                  <use xlink:href="#${icon}"></use>
              </svg>
          `;
  };

  const setPosition = (elm: HTMLElement) => {
    elm.style.position = "absolute";
    elm.style.right = "20px";
    elm.style.top = "25px";
    elm.style.transform = "translateY(-50%)";
  };

  // 创建导航栏
  const createNav = (
    node: HTMLElement,
    data: Array<INavigationItem>,
    child: boolean,
    len: number,
    level: number
  ) => {
    if (!data || data.length < 1) return false;
    let itemList = null;
    let list: Element | null = null;
    for (let i = 0; i < data.length; i++) {
      const box = createElement("div", {
        class: "box",
        pathName: data[i].name,
      });
      const item = createElement("p", { class: "item" }, data[i].title);
      const move = createElement("div", { class: "move" });
      const icon = createIcon(data[i].icon);
      const text = item.childNodes[0];
      const menuText = `<span class="v-menu-text">${text.textContent}</span>`;
      item.innerHTML = icon + menuText;

      if (child && level > 1) {
        const padding = (level + 1) * 10;
        item.style.padding = `0 ${padding}px`;
      }
      
      // 如果有子节点
      const hasChild = data[i].children && data[i].children.length > 0;
      if (hasChild) {
        // 创建item-list
        itemList = document.createElement("div");
        itemList.classList.add("item-list");
        const flag = createIcon("custom-icon-jiantou1", true);
        item.innerHTML = icon + menuText + flag;
        // @ts-ignore
        setPosition(item.children[2]);
        box.dataset.show = "0";
        box.dataset.launched = "1"; // 是否可以展开
        // 递归创建子组件
        // @ts-ignore
        list = createNav(
          itemList,
          data[i].children,
          true,
          data[i].children.length,
          level + 1
        );
        box.insertBefore(move, box.children[0]);
        box.insertBefore(item, move);
        node.appendChild(box);
        if (list) {
          ((l: Element) =>
            setTimeout(() => box.insertAdjacentHTML("afterend", l.outerHTML)))(list);
        }
        if (child && i == len - 1) return node;
      }
      if (box.children.length < 1) {
        box.appendChild(item);
        box.appendChild(move);
      } else {
        box.insertBefore(move, box.children[0]);
        box.insertBefore(item, move);
      }
      node.appendChild(box);
      if (child && i == len - 1) {
        return node;
      }
    }
  };

  // 迭代move
  const iteratorMove = (cb: Function) => {
    // @ts-ignore
    [...document.getElementsByClassName("move")].forEach((node: HTMLElement) => cb(node));
  }

  // menu-post-item-txt迭代器
  const iteratorMenuPosItemTxt = (cb: Function) => {
    const nodes = navicationDom.value?.querySelectorAll('.v-menu-pos-item-txt');
    // @ts-ignore
    [...nodes].forEach(node => cb(node));
  }

  // 清除move
  const clearMove = () => {
    iteratorMove((node: HTMLElement) => {
       node.parentNode && ((node.parentNode as HTMLElement).style.color = "#eee");
       node.classList.remove("active-move");
    })
  };

  const controlChildShow = (elm: Element, show: boolean) => {
    const list = elm.nextElementSibling;
    
    // @ts-ignore
    const boxes = list.children;
    // @ts-ignore
    list.style.height = show ? `${boxes.length * HEIGHT}px` : "";
    // show ? list.classList.add("show") : list.classList.remove("show");
  };

  // @ts-ignore
  const routerLink = (name: string, method: string = 'push', path?: string) => path ? router[method]({ path }) : router[method]({ name });

  // 切换导航栏展开状态
  const shiftNavShowState = (event: any, shift?: boolean) => {
    const elm = event.target.parentNode;
    const move = elm.children[1];
    const { show, launched } = elm.dataset;
    // 如果不可以展开的话, 就是直接跳转
    if (launched != 1) {
      // 直接跳转 清除move
      clearMove();
      elm.style.color = primaryColor;
      move.classList.add("active-move");
      routerLink(elm.getAttribute("pathName"));
      return false;
    } else {
      if (!trigger.value && !shift) return false;
      const item = elm.children[0];
      const svg = item.children[2];
      // 关闭
      if (show == 1) {
        elm.dataset.show = 0;
        svg.style.transform = "translateY(-50%) rotate(0deg)";
        controlChildShow(elm, false);
      } else {
        // 关闭其他所有菜单
        if (props.uniqueOpened) {
          // @ts-ignore
          const itemList = navicationDom.value.getElementsByClassName("item-list");
          [...itemList].forEach((elm) => {
            // @ts-ignore
            const height = elm.style.height;
            if (height) {
              shiftNavShowState(createEventObj(elm.previousElementSibling));
            }
          });
        }
        // 展开
        elm.dataset.show = 1;
        svg.style.transform = "translateY(-50%) rotate(180deg)";
        controlChildShow(elm, true);
      }
    }
  };

  // 创建导航定位节点
  const createMenuPosElm = (parent: Element, top: number, width: number) => {
    const pathName = parent.getAttribute("pathName");
    const menu = navication.filter((item: any) => item.name === pathName);
    if (menu.length > 0 && menu[0].children.length > 0) {
      const children = menu[0].children;
      const childLen = children.length;
      const wrapper = createMenuPosWrapper(width, childLen, top);
      const inners: Array<HTMLElement> = createMenuPosInner(children);
      inners.forEach((inner: HTMLElement) => wrapper.appendChild(inner));
      parent.appendChild(wrapper);
    }
  }

  // 创建导航定位节点父节点
  const createMenuPosWrapper: (w: number, c: number, t: number) => HTMLElement = (width, childLen, top) => {
    const wrapper = createElement("div", { class: "v-menu-pos" });
    wrapper.style.left = `${width + 1}px`;
    wrapper.style.top = `${top}px`;
    wrapper.style.height = `${childLen * 50}px`;
    wrapper.style.zIndex = '2';
    return wrapper;
  }

  // 清除menu-pos-item-txt的颜色
  const clearMenuPosItemTxt = () => iteratorMenuPosItemTxt((node: HTMLElement) => node.style.color = $bg.value);

  // 创建导航定位节点子节点
  const createMenuPosInner: (c: Array<any>) => Array<HTMLElement> = (list) => {

    // 递归创建元素
    const recusionCreateElm: (c: Array<any>) => Array<any> = (children) => {
      // 创建点击事件
      const createMenuPosEvent = (el: HTMLElement, data: any) => el.addEventListener('click', (event: Event) => {
        event.stopPropagation();
        clearMove();
        clearMenuPosItemTxt();
        routerLink(data.name);
        const parent = (event.target as HTMLElement).parentNode;
        const child = parent?.querySelector('.v-menu-pos-item-txt');
        (child as HTMLElement).style.color = primaryColor;

        // 点击的时候要选中父级
        iteratorMove((node: HTMLElement) => {
          const parent: any = node.parentNode;
          const { launched } = parent?.dataset;
          if (launched == 1) {
            const children = parent.querySelectorAll('.v-menu-pos-item-txt');
            children.forEach((child: HTMLElement) => {
              const pathName = child.dataset.pathName;
              if (pathName === data.name) {
                const move: HTMLElement = parent.querySelector(".move");
                move.classList.add('active-move');
              }
            })
          }
        })
      });

      // 先创建children
      const inner = children.map(child => {
        const elm = createElement("div", { class: "v-menu-pos-item" });
        const move = createElement("div", { class: "move" });
        elm.style.width = "100%";
        elm.style.height = "50px";
        elm.style.lineHeight = "50px";
        elm.style.padding = "0 10px";
        elm.style.transition = "all .25s ease-out";
        const txt = document.createElement('span');
        txt.classList.add('v-menu-pos-item-txt');
        txt.dataset.pathName = child.name;
        txt.innerText = child.title;
        elm.appendChild(txt);
        elm.appendChild(move);
        if (child.children && child.children.length > 0) {
          elm.innerHTML += createIcon("custom-icon-jiantou2");
          const childInner = recusionCreateElm(child);
          childInner.forEach(ci => elm.appendChild(ci));
        }
        createMenuPosEvent(elm, child);
        return elm;
      });

      return inner;
    }

    return recusionCreateElm(list);
  }

  // 导航栏移入
  const menuEnter = (event: any) => {
    if (!trigger.value) {
      const elm = event.target;
      const { top, width } = elm.getBoundingClientRect();
      createMenuPosElm(elm, top, width);
      iteratorMenuPosItemTxt((node: HTMLElement) => (node.dataset.pathName === actived.value) && (node.style.color = primaryColor));
    }
  }
  // 导航栏移出
  const menuLeave = (event: any) => {
    if (!trigger.value) {
      const elm = event.target;
      const menuPos = elm.querySelector(".v-menu-pos");
      if (menuPos) {
        elm.removeChild(menuPos);
      }
    }
  }

  // 给嵌套导航栏加事件
  const createEvent = () => {
    const boxes = document.getElementsByClassName("box");
    for (let i = 0; i < boxes.length; i++) {
      boxes[i].addEventListener("click", shiftNavShowState);
      boxes[i].addEventListener("mouseenter", menuEnter);
      boxes[i].addEventListener("mouseleave", menuLeave);
    }
  };

  // 获取dom节点
  // @ts-ignore
  const getNavicationVdom = (el: Element) => (navicationDom.value = el);

  // 创建event对象
  const createEventObj = (node: any) => ({
    target: {
      parentNode: node,
    },
  });

  // 选中导航栏
  const activeIndex = () => {
    const name = route.name || defaultActive;
    actived.value = name as string;
    const boxes = document.getElementsByClassName("box");
    for (let i = 0; i < boxes.length; i++) {
      const elm = boxes[i];
      const pathName = elm.getAttribute("pathName");
      if (pathName === name) {
        // 如果active的导航栏是一个单导航栏的话, 这样做是没问题的
        // 把elm的上一级给取出来
        const firstParent = elm.parentElement;
        const isChild =
          firstParent !== null
            ? [...firstParent.classList].indexOf("item-list") !== -1
            : false;
        // 是子节点(要展开父节点)
        if (isChild) {
          const siblingNode = (firstParent as Element).previousElementSibling;
          shiftNavShowState(createEventObj(siblingNode));
          shiftNavShowState(createEventObj(elm));
        } else {
          shiftNavShowState(createEventObj(elm));
        }
      }
    }
  };

  // 切换导航栏是否展开
  const handleTriggerMenu = () => trigger.value = !trigger.value;

  return {
    navication,
    getNavicationVdom,
    activeIndex,
    createEvent,
    navicationDom,
    trigger,
    createEventObj,
    shiftNavShowState,
    createNav,
    handleTriggerMenu
  }
}


export { useNavigation };